//
//  NetResponse.swift
//  kano
//
//  Created by Frank on 2024/8/26.
//

import KakaJSON

struct NetResponse<Element>: Convertible {
    let voucherQuantity: Element? = nil
    let verificationDigit: String = ""
    private(set) var operationalStatus: Int = 0
}

struct KAContent: Convertible, Codable {
    var authenticationToken: String = ""
    var operationalStatus: Int = 0
    var validationOutcome: Int = 0
    var creditComponent: String = ""
    var voucherImageURL: String = ""
    var waitingStateVariant: Int = 0
}

//struct KAApplyResponse: Convertible, Codable {
//    var data: [String : Any]?
//    var operationResult: String = ""
//    var resultMessage: String = ""
//}

typealias NetHandler<T> = (_ isSuccess: Bool, _ message: String, _ response: NetResponse<T>?) -> ()

extension NetResponse {
    //MARK: Response handle
    static func handleResponseData(_ data: Data, result:NetHandler<Element>) {
        guard let responseString = String(data: data, encoding: .utf8) else {
            return result(false,"", nil)
        }
        var decryptString: String
        if responseString.isEmpty {
            return result(false,"The returned data is empty", nil)
        }
        if responseString.isHexString() {
            decryptString = KAEncrypt.ka_decrypt(responseString)
        } else {
            decryptString = responseString
        }
        let responseDic = dealStringToObject(with: decryptString) as! Dictionary<String, Any>
        let response = responseDic.kj.model(NetResponse<Element>.self)
        if response.operationalStatus == 0 {
            return result(true,response.verificationDigit, response)
        } else {
            if [7, 17, 2200, 100008, 100009].contains(response.operationalStatus) {
                let message = "Login has expired, please log in again"
                let alert = KAAlertView.alert(withTitle: "Tips", subtitle: message) { _ in
                    
                }
                alert.addAction(KAAlertAction(title: "I known", titleColor: .blue, backgroundColor: .clear) { action in
                    KAUserManager.shared.userLogout()
                })
                alert.show()
            }
            return result(false,response.verificationDigit, response)
        }
        
        //        let responseValue = dealStringToDictionary(with: decryptString)
        //        if let responseData = responseValue as? Dictionary<String, Any> {
        //            let response = responseData.kj.model(NetResponse<T>.self)
        //            if response.operationalStatus == 0 {
        //                return result(true,response.verificationDigit, response)
        //            } else {
        //                return result(false,response.verificationDigit, response)
        //            }
        //        } else if let responseData = responseValue as? Array<Any> {
        //            return result(true, "", responseData)
        //        }
        
    }
}

func dealStringToObject(with decryptString: String?) -> Any? {
    guard let decryptString = decryptString else {
        return nil
    }
    guard let data = decryptString.data(using: .utf8) else {
        return nil
    }
    do {
        let responseObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments)
        
        if let stringResponse = responseObject as? String {
            return dealStringToObject(with: stringResponse)
        } else if let dictionaryResponse = responseObject as? [String: Any] {
            return dictionaryResponse
        } else if let arrayResponse = responseObject as? [Any] {
            return arrayResponse
        } else {
            return nil
        }
    } catch {
        return nil
    }
}



struct ApplyResponse<Element>: Convertible {
    let data: Element? = nil
    let resultMessage: String = ""
    private(set) var operationResult: String = ""
}

struct KAPickerData : Convertible {
    var entityIdentifier: Int = 0
    var level: Int = 0
    var country: String = ""
    var field: String = ""
    var reportingStructure: String = ""
    var monetaryValue: String = ""
    var parent: String = ""
    var children: [KAPickerData]?
}

typealias ApplyHandler<T> = (_ isSuccess: Bool, _ message: String, _ response: ApplyResponse<T>?) -> ()

extension ApplyResponse {
    static func handleApplyResponse(_ data: Data, result:ApplyHandler<Element>) {
        guard let responseString = String(data: data, encoding: .utf8) else {
            return result(false,"", nil)
        }
        var decryptString: String
        if responseString.isEmpty {
            return result(false,"The returned data is empty", nil)
        }
        if responseString.isHexString() {
            decryptString = KAEncrypt.ka_decrypt(responseString)
        } else {
            decryptString = responseString
        }
        let responseDic = dealStringToObject(with: decryptString) as! Dictionary<String, Any>
        let response = responseDic.kj.model(ApplyResponse<Element>.self)
        if response.operationResult == "0000" {
            return result(true,response.resultMessage, response)
        } else {
            return result(false,response.resultMessage, response)
        }
        
    }
}
